/**
 * Copyright phonemap.com
 *
 * Licensed under the phonemap.com License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.phonemap.com/licenses/LICENSE-1.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.phonemap;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.datastore.Entity;
import com.phonemap.common.AppConstant;
import com.phonemap.common.Util;
import com.phonemap.dto.PositionDTO;
import com.phonemap.models.Follow;
import com.phonemap.models.Position;
import com.phonemap.models.User;

/**
 * The Class FollowServlet.
 */
@SuppressWarnings("serial")
public class FollowServlet extends BaseServlet {

	/** The Constant logger. */
	private static Logger logger = Logger.getLogger(FollowServlet.class
			.getCanonicalName());

	/**
	 * Get the requested customer entities in JSON format.
	 * 
	 * @param req
	 *            the req
	 * @param resp
	 *            the resp
	 * @throws ServletException
	 *             the servlet exception
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	protected final void doGet(final HttpServletRequest req,
			final HttpServletResponse resp) throws ServletException,
			IOException {
		super.doGet(req, resp);
		logger.log(Level.INFO, "Obtaining Follow listing");
		// Follow.deleteAllFollows();
		String userId = req.getParameter("userId");
		String action = AppConstant.EMPTY_STRING;
		if (req.getParameter("action") != null) {
			action = req.getParameter("action");
		}
		PrintWriter out = resp.getWriter();
		if (action.equalsIgnoreCase("isExist")) {
			String followId = req.getParameter("followId");
			Entity entity = Follow.getSingleFollow(Long.parseLong(userId),
					Long.parseLong(followId));
			List<Entity> entities = new ArrayList<>();
			if (entity != null) {
				entities.add(entity);
			}
			out.println(Util.writeJSON(entities));
		} else if (action.equalsIgnoreCase("getFollows")) {
			//FIXME paging for getting follows
			List<Entity> users = Follow.getFollows(Long.parseLong(userId), 0);
			out.println(Util.writeJSON(users));
		} else if (action.equalsIgnoreCase("getFollowCount")) {
			int count = Follow.getFollowCount(Long.parseLong(userId));
			out.println(Util.writeJSON("count", Integer.toString(count)));
		} else if (action.equalsIgnoreCase("getHitory")) {
			List<PositionDTO> positions = new ArrayList<>();
			if (userId != null && !userId.equals(AppConstant.EMPTY_STRING)) {
				positions = Position.getHistory(Long.parseLong(userId),
						AppConstant.MAX_DAY, 0);
			}
			out.println(Util.writePositionJSON(positions));
		} else if (action.equalsIgnoreCase("getRequests")) {
			String offset = req.getParameter("offset");
			List<Entity> requests = Follow.getRequests(Long.parseLong(userId),
					Integer.parseInt(offset));
			out.println(Util.writeJSON(requests));
		} else if (action.equalsIgnoreCase("getFollowedList")) {
			String offset = req.getParameter("offset");
			List<Entity> followedList = Follow.getFollowedList(
					Long.parseLong(userId), Integer.parseInt(offset));
			out.println(Util.writeJSON(followedList));
		}  else {
			Iterable<Entity> entities = null;
			if (userId != null && !userId.equals(AppConstant.EMPTY_STRING)) {
				//FIXME paging for getting follows
				entities = Follow.getFollows(Long.parseLong(userId), 0);
				out.println(Util.writeJSON(entities));
			} else {
				entities = Follow.getAllFollows();
				out.println(Util.writeJSON(entities));
			}
		}
		return;
	}

	/**
	 * Insert the new customer.
	 * 
	 * @param req
	 *            the req
	 * @param resp
	 *            the resp
	 * @throws ServletException
	 *             the servlet exception
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	protected final void doPut(final HttpServletRequest req,
			final HttpServletResponse resp) throws ServletException,
			IOException {
		logger.log(Level.INFO, "Creating Follow");

		String action = req.getParameter("action");
		if (action.equalsIgnoreCase("update")) {
			doUpdate(req, resp);
		}
	}

	/**
	 * Update the user.
	 * 
	 * @param req
	 *            the req
	 * @param resp
	 *            the resp
	 * @throws ServletException
	 *             the servlet exception
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	protected final void doUpdate(final HttpServletRequest req,
			final HttpServletResponse resp) throws ServletException,
			IOException {
		logger.log(Level.INFO, "Updating Follow");
		long userId = Long.parseLong(req.getParameter("userId"));
		long followId = Long.parseLong(req.getParameter("followId"));
		String checked = req.getParameter("checked");
		String friendName = req.getParameter("friendName");
		if (checked.equalsIgnoreCase("true")) {
			Entity friend = User.getUser(followId);
			if (friend == null) {
				User.insertUser(followId, friendName);
			}
			Follow.insertFollow(userId, followId);
		} else {
			Follow.deleteFollow(userId, followId);
		}
	}

	/**
	 * Delete the customer.
	 * 
	 * @param req
	 *            the req
	 * @param resp
	 *            the resp
	 * @throws ServletException
	 *             the servlet exception
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	protected final void doDelete(final HttpServletRequest req,
			final HttpServletResponse resp) throws ServletException,
			IOException {
		String userId = req.getParameter("userId");
		String followId = req.getParameter("followId");
		logger.log(Level.INFO, "Deleting Follow (" + userId + "," + followId
				+ ")");
		Follow.deleteFollow(Long.parseLong(userId), Long.parseLong(followId));

	}

	/**
	 * Redirect the call to doDelete or doPut method.
	 * 
	 * @param req
	 *            the req
	 * @param resp
	 *            the resp
	 * @throws ServletException
	 *             the servlet exception
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	protected final void doPost(final HttpServletRequest req,
			final HttpServletResponse resp) throws ServletException,
			IOException {
		String action = req.getParameter("action");
		if (action.equalsIgnoreCase("delete")) {
			doDelete(req, resp);
			return;
		} else if (action.equalsIgnoreCase("put")) {
			doPut(req, resp);
			return;
		} else if (action.equalsIgnoreCase("update")) {
			doUpdate(req, resp);
			return;
		} else if (action.equalsIgnoreCase("insert")) {
			doInsert(req, resp);
			return;
		} else if (action.equalsIgnoreCase("confirm")) {
			doConfirm(req, resp);
			return;
		}
	}

	/**
	 * Update the user.
	 * 
	 * @param req
	 *            the req
	 * @param resp
	 *            the resp
	 * @throws ServletException
	 *             the servlet exception
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	protected final void doInsert(final HttpServletRequest req,
			final HttpServletResponse resp) throws ServletException,
			IOException {
		logger.log(Level.INFO, "Creating Follow");

		String userId = req.getParameter("userId");
		String followId = req.getParameter("followId");

		Follow.insertFollow(Long.parseLong(userId), Long.parseLong(followId));
	}

	/**
	 * Do confirm.
	 * 
	 * @param req
	 *            the req
	 * @param resp
	 *            the resp
	 * @throws ServletException
	 *             the servlet exception
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	protected final void doConfirm(final HttpServletRequest req,
			final HttpServletResponse resp) throws ServletException,
			IOException {
		logger.log(Level.INFO, "confirming Follow");

		String userId = req.getParameter("userId");
		String followId = req.getParameter("followId");

		Follow.confirmFollow(Long.parseLong(followId), Long.parseLong(userId));
	}

}
